package hmy.com;

import hmy.com.model.Coffee;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.Banner;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.scheduler.Schedulers;

import javax.annotation.Resource;
import java.net.URI;
import java.util.concurrent.CountDownLatch;

@Slf4j
@SpringBootApplication
public class Application implements ApplicationRunner {

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private WebClient webClient;

    public static void main(String[] args) {
        new SpringApplicationBuilder()
                .sources(Application.class)
                .bannerMode(Banner.Mode.OFF)
                .web(WebApplicationType.NONE)
                .run(args);
    }

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }

    @Bean
    public WebClient webClient(WebClient.Builder builder) {
        return builder.baseUrl("http://localhost:8082").build();
    }


    @Override
    public void run(ApplicationArguments args) throws Exception {
        URI uri = UriComponentsBuilder
                .fromUriString("http://localhost:8082/coffee/{id}")
                .build(1);
        HttpHeaders headers = new HttpHeaders();

        headers.set("Content-Type","application/xml");
        ResponseEntity<String> xmlResult = restTemplate.exchange(uri, HttpMethod.GET,new HttpEntity<>(null, headers),String.class);
        log.info("Response Status: {}, Response Headers: {}", xmlResult.getStatusCode(), xmlResult.getHeaders().toString());
        log.info("Coffee: {}", xmlResult.getBody());

        headers.set("Content-Type","application/json;charset=UTF-8");
        ResponseEntity<Coffee> jsonResult = restTemplate.exchange(uri, HttpMethod.GET,new HttpEntity<>(null, headers),Coffee.class);
        log.info("Response Status: {}, Response Headers: {}", jsonResult.getStatusCode(), jsonResult.getHeaders().toString());
        log.info("Coffee: {}", jsonResult.getBody());

        CountDownLatch cdl = new CountDownLatch(2);

        webClient.get()
                .uri("/coffee/{id}", 1)
                .headers(httpHeaders -> headers.set("Content-Type","application/xml"))
                .accept(MediaType.APPLICATION_XML)
                .retrieve()
                .bodyToMono(String.class)
                .doOnError(t -> log.error("Error: ", t))
                .doFinally(s -> cdl.countDown())
                .subscribeOn(Schedulers.single())
                .subscribe(c -> log.info("Coffee 1: {}", c));

        webClient.get()
                .uri("/coffee/{id}", 1)
                .headers(httpHeaders -> headers.set("Content-Type","application/json;charset=UTF-8"))
                .accept(MediaType.APPLICATION_JSON_UTF8)
                .retrieve()
                .bodyToMono(Coffee.class)
                .doOnError(t -> log.error("Error: ", t))
                .doFinally(s -> cdl.countDown())
                .subscribeOn(Schedulers.single())
                .subscribe(c -> log.info("Coffee 1: {}", c));
        cdl.await();
    }

}
